package controllers

import java.io.File

import dao._
import javax.inject.Inject
import play.api.libs.json.Json
import play.api.mvc.{AbstractController, ControllerComponents}
import tool.{FormTool, Tool}
import utils.Utils

import scala.concurrent.ExecutionContext.Implicits.global
import implicits.Implicits._
import models.Tables.JunctionRow
import shared.VarTool

/**
 * Created by yz on 11/5/2020
 */
class BrowseController @Inject()(cc: ControllerComponents, junctionDao: JunctionDao)(
  implicit val modeDao: ModeDao) extends AbstractController(cc) {

  def toIndex = Action { implicit request =>
    Ok(views.html.browse.index(None))
  }

  def getAllGeneTypes = Action.async { implicit request =>
    junctionDao.selectAllGeneTypes.map { x =>
      Ok(Json.toJson(x))
    }
  }

  def getAllJunctionTypes = Action.async { implicit request =>
    junctionDao.selectAllJunctionTypes.map { x =>
      Ok(Json.toJson(x))
    }
  }

  def getAllAnnotation = Action.async { implicit request =>
    junctionDao.selectAllAnnotation.map { x =>
      Ok(Json.toJson(x))
    }
  }

  def getAllTumorTypes = Action.async { implicit request =>
    junctionDao.selectAllTumorTypes.map { x =>
      val types = x.flatMap { x =>
        x.mySplit(";").map(_.mySplit("\\(")(0))
      }.distinct
      Ok(Json.toJson(types))
    }
  }

  def browse = Action.async { implicit request =>
    val data = FormTool.browseForm.bindFromRequest().get
    junctionDao.selectAll(data).map { x =>
      val json = Utils.getJsonByTs(x)
      Ok(json)
    }
  }

  def browseBefore = Action { implicit request =>
    val data = FormTool.kindForm.bindFromRequest().get
    Ok(views.html.browse.index(data.kind))
  }

  def getAllJunctionByServer = Action.async { implicit request =>
    val page = FormTool.pageForm.bindFromRequest.get
    val offSet = page.offset
    val limit = page.limit
    junctionDao.selectAll(page).map { case (size, x) =>
      val array = x.map { y =>
        Utils.getJsonByT(y)
      }
      Ok(Json.obj("rows" -> array, "total" -> size))
    }
  }

  def downloadAllJunction = Action.async { implicit request =>
    val junctionIds = FormTool.junctionIdsForm.bindFromRequest().get.junctionIds
    val tmpDir = Tool.createTempDirectory("tmpDir")
    val outFile = new File(tmpDir, "out.csv")
    junctionDao.selectAllByJunctionIds(junctionIds).map { samples =>
      case class OutJunctionData(junctionId: String, junctionLocation: String, junctionType: String, geneSymbol: String,
                                 geneType: String, transcriptId: String, tumorMedian: String, ntMedian: String,
                                 normalMedian: String, tumorFreq: String, ntFreq: String, normalFreq: String,
                                 tumorSpecificTypes: String, alternativeSplicingTypes: String, annotation: String)
      samples.toList.map(x => x.migrateTo[OutJunctionData]).lines.convertHeaderIgnoreCase(VarTool.junctionMap).
        toFile(outFile)
      Ok.sendFile(outFile, onClose = () => {
        Tool.deleteDirectory(tmpDir)
      })
    }
  }


}
